﻿using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
using System.IO;
using System.IO.Ports;
using SecretLabs.NETMF.IO;
using GPS.GPSLanguage;

namespace netdreamo
{
    public class Program
    {
        private static NMEAParser parser;

        static FileStream dataStream;
        //create the sd card connection
        static string root = "SD_Card";
        static string path = Path.Combine(root, "test.kml");
        static AnalogInput intTemp;
        static AnalogInput extTemp;

        static OutputPort buzzer = new OutputPort(Pins.GPIO_PIN_D6, false);
        
        static OutputPort LED = new OutputPort(Pins.ONBOARD_LED, false);

        static int ind = 0;

        public static void Main()
        {
            //Set up a Serial Port pointing to COM1            
            SerialPort p = new SerialPort("COM1", 4800, Parity.None, 8, StopBits.One);

            //Set up a GPSDataStream object using the serial port set up above
            GPSDataStream stream = new GPSDataStream(p, 250);

            //Create our nmeaparser object
            parser = new NMEAParser();

            //Set up our Event handler to catch sentences once they've been captured from
            //the gps device
            stream.SentenceIsReady += new GPSDataStream.GPSSentenceReady(stream_SentenceIsReady);

            //Set up our Event Handlers for GPS Sentences once they've been parsed
            parser.GPGGADataReady += new NMEAParser.GPSDataReadyEvent(parser_GPGGADataReady);
           
            //create the temp sensor inputs
            intTemp = new AnalogInput(Pins.GPIO_PIN_A0);
            extTemp = new AnalogInput(Pins.GPIO_PIN_A1);

            //init the SD connection
            StorageDevice.MountSD(root, SPI.SPI_module.SPI1, Cpu.Pin.GPIO_Pin12);

            //setup the sd card            
            string content;
            byte[] bytes;

            //datastream to put data to the sd card
            dataStream = new FileStream(path, FileMode.Create, FileAccess.Write);
            
            //write a kml header
            content = writeHeader("High Altitude Balloon Project", DateTime.Now.ToString());
            bytes = System.Text.Encoding.UTF8.GetBytes(content);
            dataStream.Write(bytes, 0, bytes.Length);

            dataStream.Dispose();

            //Sleep and wait for events to fire
            Thread.Sleep(Timeout.Infinite);
        }

        public static string writeHeader(string name, string date)
        {
            return "<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n" +
                             "\t<Document>\n" +
                             "\t\t<name>" + name + "</name>\n" +
                             "\t\t<date>" + date + "</date>\n";
        }

        public static string writePlacemark(string name, string inTemp, string extTemp, string gpsAlt, string gpsTrack, string gpsTime, string coordinates)
        {
            return
                "\t\t\t<Placemark>\n" +
                "\t\t\t\t<name>" + name + "</name>\n" +
                "\t\t\t\t<ExtendedData>\n" +

                "\t\t\t\t\t<Data name=\"internalTemp\">\n" +
                "\t\t\t\t\t\t<value>" + inTemp + "</value>\n" +
                "\t\t\t\t\t</Data>\n" +

                "\t\t\t\t\t<Data name=\"externalTemp\">\n" +
                "\t\t\t\t\t\t<value>" + extTemp + "</value>\n" +
                "\t\t\t\t\t</Data>\n" +

                "\t\t\t\t\t<Data name=\"gpsAltitude\">\n" +
                "\t\t\t\t\t\t<value>" + gpsAlt + "</value>\n" +
                "\t\t\t\t\t</Data>\n" +

                "\t\t\t\t\t<Data name=\"gpsTrack\">\n" +
                "\t\t\t\t\t\t<value>" + gpsTrack + "</value>\n" +
                "\t\t\t\t\t</Data>\n" +

                "\t\t\t\t\t<Data name=\"gpsTime\">\n" +
                "\t\t\t\t\t\t<value>" + gpsTime + "</value>\n" +
                "\t\t\t\t\t</Data>\n" +

                "\t\t\t\t</ExtendedData>\n" +

                "\t\t\t\t\t<Point>\n" +
                "\t\t\t\t\t\t<coordinates>" + coordinates + "</coordinates>\n" +
                "\t\t\t\t\t</Point>\n" +

                "\t\t\t</Placemark>\n";
        }

        public static string writeFooter()
        {
            return "\t</Document>\n" +
                        "</kml>";
        }

        //Fires every time a sentence is ready (fired from the GPSDataStream)
        static void stream_SentenceIsReady(GPSDataStream sender, string sentence)
        {
            parser.ParseGPSString(sentence, true);
        }

        //Fires every time a GPGGA sentence has been parsed (fired from NMEA Parser)
        static void parser_GPGGADataReady(NMEAParser sender, GPSData data)
        {
            Debug.Print(data.ToString());

            dataStream = new FileStream(path, FileMode.Append, FileAccess.Write);

            //get the data from the gps
            string alt = data.Altitude.ToString();
            string track = data.TrackAngle.ToString();
            string time = data.TimeTaken.ToString();
            string lat = data.LatitudeDecimalDegrees.ToString();
            string lon = data.LongitudeDecimalDegrees.ToString();
            string coords = lon + "," + lat + "," + alt;

            //flash and buzz
            buzzer.Write(true);
            LED.Write(true);

            Thread.Sleep(100);

            buzzer.Write(false);
            LED.Write(false);

            //format a kml placemark
            string content = writePlacemark(
                "Point " + ind.ToString(),
                intTemp.Read().ToString(),
                extTemp.Read().ToString(),
                alt,
                track,
                time,
                coords);

            //write the placemark to the sd card
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(content);
            dataStream.Write(bytes, 0, bytes.Length);

            dataStream.Dispose();

            ind++;

            
        }

    }
}
